package com.extremelylargepackage;

import java.io.InputStream;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.content.res.AssetManager;
import android.util.Log;

import com.extremelylargepackage.entity.AiAimedAttack;
import com.extremelylargepackage.entity.AiAttackComponent;
import com.extremelylargepackage.entity.AiAvoid;
import com.extremelylargepackage.entity.AiBrave;
import com.extremelylargepackage.entity.AiKamikaze;
import com.extremelylargepackage.entity.AiListless;
import com.extremelylargepackage.entity.AiMoveComponent;
import com.extremelylargepackage.entity.AiRandomAttack;
import com.extremelylargepackage.entity.AiRandomMove;
import com.extremelylargepackage.entity.AiSeeker;
import com.extremelylargepackage.entity.ArtificialIntelligence;
import com.extremelylargepackage.entity.Enemy;
import com.extremelylargepackage.entity.EntityFactory;
import com.extremelylargepackage.entity.EntityFactory.EntityType;
import com.extremelylargepackage.entity.Weapon;
import com.extremelylargepackage.sprite.AbstractSprite;
import com.extremelylargepackage.sprite.Animation;
import com.extremelylargepackage.sprite.AnimationParser;

public class EnemyParser 
{

	public static HashMap<String, Enemy> loadEnemies(AssetManager a) 
	{
		HashMap<String,Enemy> enemies = new HashMap<String,Enemy>();
		String[] paths = null;
		try
		{
			paths = a.list("enemy");
			for(int i = 0; i < paths.length; i++)
			{
				InputStream stream = a.open("enemy/" + paths[i]);
				Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream);
				Element root = doc.getDocumentElement();
				root.normalize();

				Enemy enemy = (Enemy) EntityFactory.createEntity(EntityType.enemy);

				String name = root.getAttribute("name");
				AbstractSprite sprite = GameResources.getResource(root.getAttribute("sprite"));
				float health = Float.parseFloat(root.getAttribute("health"));
				//As a percentage of screen width / sec
				float speed = Float.parseFloat(root.getAttribute("speed"));

				NodeList nodes = root.getChildNodes();
				Weapon weapon = null;
				ArtificialIntelligence ai = null;
				Animation explosion = null;
				int collisionDamage = 0;
				for(int j = 0; j < nodes.getLength(); j++)
				{
					Node node = nodes.item(j);
					if(node.getNodeName().equals("Weapon"))
					{
						weapon = GameResources.getWeapon(((Element)node).getAttribute("type"));
					}
					else if(node.getNodeName().equalsIgnoreCase("AI"))
					{
						ai = parseAi((Element)node);
					}
					else if(node.getNodeName().equalsIgnoreCase("Explosion"))
					{
						explosion = AnimationParser.parseAnimation(((Element)node).getAttribute("animation"));
					}
					else if(node.getNodeName().equalsIgnoreCase("Collision"))
					{
						collisionDamage = Integer.parseInt(((Element)node).getAttribute("playerDamage"));
					}
				}

				EntityFactory.setName(enemy, name);
				EntityFactory.setSprite(enemy, sprite);
				EntityFactory.setEnemyProperties(enemy, speed * GameResources.SCREEN_WIDTH, weapon, health, explosion, collisionDamage);
				EntityFactory.setEnemyAi(enemy, ai);
				if(weapon != null)
					EntityFactory.SetWeaponOwner(weapon, enemy);
				
				enemies.put(name, enemy);
			}
		}
		catch(Exception e)
		{
			Log.e("ERROR PARSING ENEMY", "",e);
		}
		return enemies;
	}
	
	private static ArtificialIntelligence parseAi(Element aiRoot)
	{
		NodeList nodes = aiRoot.getChildNodes();
		ArtificialIntelligence ai = null;
		AiAttackComponent attack = null;
		AiMoveComponent move = null;
		for(int k = 0; k < nodes.getLength(); k++)
		{
			Node node = nodes.item(k);
			if(node.getNodeName().equals("MoveComponent"))
			{
				String type = ((Element)node).getAttribute("type");
				if(type.equalsIgnoreCase("Kamikaze"))
				{
					boolean seek = Boolean.parseBoolean(((Element)node).getAttribute("seek"));
					boolean linear = Boolean.parseBoolean(((Element)node).getAttribute("linear"));
					move = new AiKamikaze(seek, linear);
				}
				else if (type.equalsIgnoreCase("Seeker"))
				{
					move = new AiSeeker(Float.parseFloat(((Element)node).getAttribute("delay"))*1000f);
				}
				else if(type.equalsIgnoreCase("Random"))
				{
					float minFreq = Float.parseFloat(((Element)node).getAttribute("minFreq"));
					float maxFreq = Float.parseFloat(((Element)node).getAttribute("maxFreq"));
					float flee = Float.parseFloat(((Element)node).getAttribute("flee"));
					move = new AiRandomMove(flee, minFreq, maxFreq);
				}
				else if(type.equalsIgnoreCase("Listless"))
				{
					move = new AiListless();
				}
				else if(type.equalsIgnoreCase("Brave"))
				{
					float lowerY = Float.parseFloat(((Element)node).getAttribute("lowerY")) * GameResources.SCREEN_HEIGHT;
					float upperY = Float.parseFloat(((Element)node).getAttribute("upperY")) * GameResources.SCREEN_HEIGHT;
					long wait = Long.parseLong(((Element)node).getAttribute("wait"));
					move = new AiBrave(lowerY, upperY, wait);
				}
				else if(type.equalsIgnoreCase("Avoid"))
				{
					move = new AiAvoid();
				}
			}
			if(node.getNodeName().equals("AttackComponent"))
			{
				String type = ((Element)node).getAttribute("type");
				if(type.equalsIgnoreCase("Random"))
				{
					float chance = Float.parseFloat(((Element)node).getAttribute("chance"));
					attack = new AiRandomAttack(chance);
				}
				else if(type.equalsIgnoreCase("Aimed"))
				{
					attack = new AiAimedAttack();
				}
			}
		}
		ai = new ArtificialIntelligence(move, attack);
		return ai;
	}

}
